#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "shared_setup.h"
#include "SDL/SDL.h"
#include "chunks/GuacInput_mouse_setup.h"
#include "guacinput.h"

static int mouse_get_position(lua_State *L)
{
    if (!mouseOnScreen)
        return 0;
    int mouseX,mouseY;
    SDL_GetMouseState(&mouseX,&mouseY);
    lua_pushinteger(L,mouseX);
    lua_pushinteger(L,mouseY);
    return 2;
}

static int mouse_get_x(lua_State *L)
{
    if (!mouseOnScreen)
        return 0;
    int mouseX;
    SDL_GetMouseState(&mouseX,NULL);
    lua_pushinteger(L,mouseX);
    return 1;
}

static int mouse_get_y(lua_State *L)
{
    if (!mouseOnScreen)
        return 0;
    int mouseY;
    SDL_GetMouseState(NULL,&mouseY);
    lua_pushinteger(L,mouseY);
    return 1;
}

static int mouse_get_onscreen(lua_State *L)
{
    lua_pushboolean(L, mouseOnScreen);
    return 1;
}

static int mouse_get_confined(lua_State *L)
{
    lua_pushboolean(L, (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON));
    return 1;
}

static int mouse_set_confined(lua_State *L)
{
    SDL_WM_GrabInput(lua_toboolean(L,2) ? SDL_GRAB_ON : SDL_GRAB_OFF);
    return 0;
}

static int mouse_get_visible(lua_State *L)
{
    lua_pushboolean(L, (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE));
    return 1;
}

static int mouse_set_visible(lua_State *L)
{
    SDL_ShowCursor(lua_toboolean(L,2) ? SDL_ENABLE : SDL_DISABLE);
    return 1;
}

static int create_mousebutton(lua_State *L)
{
    *(int*)lua_newuserdata(L, sizeof(int)) = luaL_checkint(L,1);
    return 1;
}

static int button_get_down(lua_State *L)
{
    int button = *(int*)lua_touserdata(L,1);
    Uint8 mask = SDL_GetMouseState(NULL, NULL);
    lua_pushboolean(L, mask & (1 << button));
    return 1;
}

static int button_get_struck(lua_State *L)
{
    int button = *(int*)lua_touserdata(L,1);
    lua_pushboolean(L, mouseButtonsDown[button]);
    return 1;
}

static int button_get_released(lua_State *L)
{
    int button = *(int*)lua_touserdata(L,1);
    lua_pushboolean(L, mouseButtonsUp[button]);
    return 1;
}

static luaL_Reg mouse_functions[] = {
    {"get_position", mouse_get_position},
    {"get_x", mouse_get_x},
    {"get_y", mouse_get_y},
    {"get_confined", mouse_get_confined},
    {"set_confined", mouse_set_confined},
    {"get_onscreen", mouse_get_onscreen},
    {"get_visible", mouse_get_visible},
    {"set_visible", mouse_set_visible},

    {"create_button", create_mousebutton},
    {"button_get_down", button_get_down},
    {"button_get_struck", button_get_struck},
    {"button_get_released", button_get_released},

    {"getmetatable", raw_getmetatable},
    {"setmetatable", raw_setmetatable},
    {"getfenv", raw_getfenv},
    {"setfenv", raw_setfenv},
    {NULL,NULL}
};

int luaopen_mouse(lua_State* L)
{
    lua_newtable(L);

    luaL_register(L, NULL, mouse_functions);

    luaL_loadbuffer(L, chunk_GuacInput_mouse_setup, sizeof(chunk_GuacInput_mouse_setup), NULL);
    lua_insert(L,-2);
    lua_call(L,1,1);

    lua_pushvalue(L,-1);
    lua_setglobal(L,"mouse");

    return 0;
}
